#include "GameCamera.h"

GameCamera::GameCamera()
{

}

GameCamera::~GameCamera()
{
    focusObject = NULL;
    mapLayer = NULL;
}

void GameCamera::initGameCamera(CCSize _cameraSize, CCRect _cameraRegion, CCLayer *_screen)
{
    this->setContentSize(_cameraSize);
    this->setAnchorPoint(CCPointMake(0.5f, 0.5f));

    mapLayer = _screen;
    layerArea = _cameraRegion;
    screenSize = CCDirector::sharedDirector()->getWinSize();
    moveSpeed = CCPointMake(10, 10);
}

void GameCamera::focusTo(CCNode *_object)
{
    focusObject = _object;
}

void GameCamera::moveToPoint(CCPoint _point, float _duration)
{
    focusObject = NULL;
    desPoint = _point;
    moveSpeed.x = (desPoint.x - this->getPositionX()) / _duration;
    moveSpeed.y = (desPoint.y - this->getPositionY()) / _duration;
}

void GameCamera::update(float delta)
{
    if (focusObject) {
        desPoint = focusObject->getPosition();
        this->setPosition(focusObject->getPosition());
    } else {
        if ((this->getPositionX() < (desPoint.x - fabs(moveSpeed.x * delta))) ||
                (this->getPositionX() > (desPoint.x + fabs(moveSpeed.x * delta)))) {
            this->setPositionX(this->getPositionX() + moveSpeed.x * delta);
        }

        if ((this->getPositionY() < (desPoint.y - fabs(moveSpeed.y * delta))) ||
                (this->getPositionY() > (desPoint.y + fabs(moveSpeed.y * delta)))) {
            this->setPositionY(this->getPositionY() + moveSpeed.y * delta);
        }
    }
    posOnScreen = ccpSub(mapLayer->getPosition(),
                         CCPointMake(mapLayer->getContentSize().width * mapLayer->getAnchorPoint().x,
                                     mapLayer->getContentSize().height * mapLayer->getAnchorPoint().y));
    posOnScreen = ccpAdd(posOnScreen, this->getPosition());

    CCPoint desPos = CCPointMake(mapLayer->getPositionX() + screenSize.width * 0.5f - posOnScreen.x,
                                       mapLayer->getPositionY() + screenSize.height * 0.5f - posOnScreen.y);
    if (this->getPositionX() - this->getContentSize().width * 0.5f < layerArea.getMinX()) {
        desPos.x -= layerArea.getMinX() + this->getContentSize().width * 0.5f - this->getPositionX();
    }
    else if (this->getPositionX() + this->getContentSize().width * 0.5f > layerArea.getMaxX()) {
        desPos.x += this->getPositionX() + this->getContentSize().width * 0.5f - layerArea.getMaxX();
    }

    if (this->getPositionY() - this->getContentSize().height * 0.5f < layerArea.getMinY()) {
        desPos.y -= layerArea.getMinY() + this->getContentSize().height * 0.5f - this->getPositionY();
    }
    else if (this->getPositionY() + this->getContentSize().height * 0.5f > layerArea.getMaxY()) {
        desPos.y += this->getPositionY() + this->getContentSize().height * 0.5f - layerArea.getMaxY();
    }

    mapLayer->setPosition(desPos);
}
